import {replaceByObj} from './xUtil.js';
import xID from "./xID.js";

/*
  cfg:{
    data:{code,name}
    placeholer:'',
    style:
  }
 */
const tmplBase = `<div class="{{class}}"  >
                    <div type="head" class="{{headClass}}">   
                      <div type="line">
                      {{lines}}
                      </div>
                      <div type="content">
                         <textarea  {{rows}} {{readonly}} {{placeholder}} wrap="hard" >{{text}}</textarea>
                      </div>
                    </div>               
                  </div>`;

const tmplLineNum ='<div type="number">{{num}}</div>';

export default class xTextarea {
    /* 定义变量 开始*/
    // jquery 对象
    $root;
    $head;
    $line;
    $text;
    $textarea;
    vBindEvent;
    vCfg;
    vInputValue;
    vClickId = 'click.'+xID.getID();
    /* 定义变量 结束*/

    constructor(cfg) {
        this.$root = $('#' + cfg.el);
        this.vCfg = cfg;
        this.renderInit();
        this.init();
    };

    static onlyRender(cfg){
        let lineHtml = "";
        let lineCount = (cfg.text||cfg.data||'').split("\n").length + 2;
        for(let i = 1; i <= lineCount; i++) {
            lineHtml += tmplLineNum.replace("{{num}}", i);
        }
        let style = cfg.style ||'textarea';
        let readonly='readonly';
        let placeholder='';
        let rows ='';
        if(cfg.rows && (cfg.rows >= lineCount+1))
            rows = 'rows="'+cfg.rows+'"';
        else
            rows = 'rows="'+(lineCount+1)+'"';

        return replaceByObj(tmplBase,{style,placeholder,rows,
            class:style,readonly,
            lines:lineHtml,text:'\n'+(cfg.text||cfg.data||''),headClass:''})
    }
    /* 渲染区块 开始 */
    init() {
        this.$head = this.$root.find('[type="head"]');
        this.$line = this.$root.find('[type="line"]');
        this.$text = this.$root.find('[type="content"]');
        this.$textarea = this.$root.find('textarea');
        this.$head.on('click', this.evClick.bind(this));
        this.$head.on('input','textarea',this.evInput.bind(this));
        this.$textarea.on('focus',this.evFocus.bind(this));
        this.$root.on('keydown',this.evKeydown.bind(this));
        this.renderLineNum();
        if(this.vCfg.active)
            this.initValue(this.vCfg.active);

        if(this.vCfg.readonly)
            this.setReadonly(true);

    };

    initValue(value){
        this.vInputValue =value;
        this.$textarea.val(this.vInputValue);
        this.renderStatus();
        this.renderLineNum();
        this.verify();
    };


    renderStatus(action,status){
        if(action=='add'){
            this.$head.addClass(status);
        }else{
            this.$head.removeClass(status);
        }
    }


    renderInit(){
        let style = this.vCfg.style ||'textarea';
        let readonly='';
        let placeholder='';
        let rows ='';
        if(this.vCfg.placeholder)
            placeholder = 'placeholder="'+this.vCfg.placeholder+'"';
        if(this.vCfg.rows)
            rows = 'rows="'+this.vCfg.rows+'"';
        if(this.vCfg.readonly)
            readonly ='readonly';
        this.$root.html(replaceByObj(tmplBase,{style,placeholder,rows,
            class:style, readonly,lines:'',text:'',headClass:'xhead'}));

    }

    renderLineNum(){
        let lineCount = 0;
        if(this.vInputValue)
            lineCount = this.vInputValue.split("\n").length+1;
        let rows = this.$textarea.prop("rows");
        if(lineCount < rows)
            lineCount = rows ;

        let child_count = this.$line[0].children.length;
        if(lineCount!=child_count ){
            let html ="";
            for(let i=1;i<=lineCount;i++){
                html += tmplLineNum.replace("{{num}}",i);
            }

            this.$line.html(html);
        }
    }

    evFocus(e){
        if(this.vCfg.readonly)
            return;
        this.renderStatus('add','active');
    }

    evKeydown(e){
        let keynum = window.event ? e.keyCode : e.which;
        switch(keynum){
            //tab 失去焦点
            case 9:
                this.evOff.bind(this)(e);
                break;
        }
    }

    evClick(e){
        if(this.vCfg.readonly)
            return;
        this.renderStatus("add","active");
        $(document).on(this.vClickId,this.evOff.bind(this));
    }

    evOff(e){
        if((e.type=='keydown') ||
            (e.type=='click' && this.$root.find(e.target).length<1)){
            this.renderStatus('remove','active');
            this.verify();
            $(document).unbind(this.vClickId);
        }
    }

    evInput(e){
        this.vInputValue = e.target.value;
        /*
        let lineHeight = this.$line.height();
        let height = this.$textarea.height();
        let scrollHeight = this.$textarea.prop("scrollHeight") ;
         */
        this.renderLineNum();
        this.renderStatus('active');
        if(this.vBindEvent)
            this.vBindEvent(this.vInputValue);
    }

    setReadonly(status){
        this.vCfg.readonly = status;
        if(status){
            this.renderStatus("add","readonly");
            this.$textarea.attr("disabled","true")
        }else{
            this.renderStatus("remove","readonly");
            this.$textarea.removeAttr("disabled")
        }
    }

    setBindEvent(event){
        this.vBindEvent = event;
    };

    setValue(value){
        this.initValue(value);
    };

    verify() {
        let result = true;
        if(this.vCfg.mandatory ){
            if(!this.vInputValue){
                this.renderStatus("remove",'valid');
                this.renderStatus("add","invalid");
                result =false
            }else {
                this.renderStatus("remove",'invalid');
                this.renderStatus("add","valid");
            }
        }
        return result;
    }

    getValue(){
        return this.vInputValue;
    }
}